SimpleMoney.java

package money;

/**
 * A simple amount of Money with its currency.
 *
 * @author Kent Beck
 * @author Robert Duvall (small updates and commenting)
 */
public class SimpleMoney extends Money {
    private final int fAmount;
    private final String fCurrency;


    /**
     * Constructs simple money from the given amount and currency.
     */
    public SimpleMoney (int amount, String currency) {
        fAmount = amount;
        fCurrency = currency;
    }

    /**
     * @see Money#add(Money)
     *
     * Forwards the request to addMoney helper, since we know what concrete type this instance is
     */
    @Override
    public Money add (Money m) {
        return m.addMoney(this);
    }

    /**
     * @see Money#subtract(Money)
     */
    @Override
    public Money subtract (Money m) {
        return add(m.negate());
    }

    /**
     * @see Money#multiply(int)
     */
    @Override
    public Money multiply (int factor) {
        return new SimpleMoney(amount() * factor, currency());
    }

    /**
     * @see Money#negate()
     */
    @Override
    public Money negate () {
        return new SimpleMoney(-amount(), currency());
    }

    /**
     * @see Money#isZero()
     */
    @Override
    public boolean isZero () {
        return amount() == 0;
    }

    /**
     * Returns only the amount of this money.
     */
    public int amount () {
        return fAmount;
    }

    /**
     * Returns only the currency of this money.
     */
    public String currency () {
        return fCurrency;
    }

    /**
     * @see Object#equals(Object)
     */
    @Override
    public boolean equals (Object anObject) {
        if (isZero()) {
            return anObject instanceof Money &&((Money) anObject).isZero();
        }
        if (anObject instanceof SimpleMoney aSimpleMoney) {
            return aSimpleMoney.currency().equals(currency()) && amount() == aSimpleMoney.amount();
        }
        return false;
    }

    /**
     * @see Object#hashCode()
     */
    @Override
    public int hashCode () {
        if (fAmount == 0) {
            return 0;
        }
        return fCurrency.hashCode() + fAmount;
    }

    /**
     * @see Object#toString()
     */
    @Override
    public String toString () {
        return "[" + amount() + " " + currency() + "]";
    }


    // Double dispatch methods --- one needed for each different subclass!
    @Override
    Money addMoney (SimpleMoney m) {
        if (m.currency().equals(currency())) {
            return new SimpleMoney(amount() + m.amount(), currency());
        }
        return MoneyBag.of(this, m);
    }

    @Override
    Money addMoneyBag (MoneyBag s) {
        return s.addMoney(this);
    }
}